package com.ctim.web.config;

import com.ctim.common.pcs.LogInfo;
import com.ctim.common.pcs.PcsResult;
import com.ctim.common.pcs.ThreadShareData;
import com.ctim.web.util.HttpTools;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Profile;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

import static net.logstash.logback.marker.Markers.appendFields;

@Aspect
@Component
@Order(5)
@Profile("aop")
public class WebLogAspect {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Pointcut("execution(public * com.ctim.web..*.*(..))")
    public void webLog(){
    }


    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes!=null) {
            HttpServletRequest request = attributes.getRequest();
            String remoteHost = HttpTools.getHttpClientIP(request);
            ThreadShareData.ip.set(remoteHost);
            LogInfo aceessLog = getAccessLog(request.getMethod()+":"+request.getRequestURI());
            // 记录下请求内容
            logger.info(appendFields(aceessLog),"access log");
        }
        /*logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));*/
    }

    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求，返回内容
        if (ret!=null && ret instanceof PcsResult) {
            LogInfo aceessLog = getResponseLog(ret);
            // WARNING:启动时不可执行此语句
            logger.info(appendFields(aceessLog),"access log");
        }
    }


    private LogInfo getAccessLog(String path) {
        String ip = ThreadShareData.ip.get();
        Integer userId = ThreadShareData.userId.get();
        LogInfo logInfo = new LogInfo(ip,userId);
        logInfo.setPath(path);
        return logInfo;
    }

    private LogInfo getResponseLog(Object ret) {
        String ip = ThreadShareData.ip.get();
        Integer userId = ThreadShareData.userId.get();
        LogInfo logInfo = new LogInfo(ip,userId);
        logInfo.setRet(ret);
        return logInfo;
    }
}